package jiang.jredis.channel;

import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;

/**
 * Redis的发布订阅接口
 * 使用时创建一个接口继承该接口
 * 并添加@Topic注解指明发布订阅的主题
 * 即可在容器中获取该接口的实例并调用方法
 * @param <T> 消息类型的泛型
 */
public interface Channel<T> {

    /**
     * 同步发布消息
     * @param message 消息对象
     */
    void publish(T message);

    /**
     * 异步发布消息
     * @param message 消息对象
     * @param executor 执行发送任务的线程池
     */
    void publishAsync(T message, Executor executor);

    /**
     * 为该Channel添加消费者
     * 在有消息时会自动执行
     * @param consumer 消费者
     * @param executor 执行消费任务的线程池
     */
    void subscribe(Consumer<T> consumer, Executor executor);

    /**
     * 为该Channel移除指定消费者
     * @param consumer 消费者
     */
    void unSubscribe(Consumer<T> consumer);

    /**
     * 阻塞接收消息
     * @return 消息对象
     */
    T receive();

    /**
     * 阻塞接收消息
     * 但只等待给定时间
     * @param timeout 等待时间
     * @param unit 时间单位
     * @return 消息对象
     */
    T receive(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException;

    /**
     * 关闭channel
     */
    void close();

}
